package com.cc.alltype;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.time.temporal.TemporalAdjusters;

public class DatetimeUtils {
    private static final String COMMON_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * 截取并转换日期 2025-05-28 11:12:13 为整型 111213 并返回
     * @param date 日期时间
     * @return
     */
    public static Integer getTimeStrInt(Date date) throws Exception {
        String dateString = formatDate(date, COMMON_PATTERN);
        String str = dateString.substring(11).replace(":", "");
        return Integer.parseInt(str);
    }
    /**
     * 2023年10月20日 15:05:46 比较日期（忽略时间）
     * @param sDate 作为减数的日期
     * @param eDate 作为被减数的日期
     * @return eDate - sDate
     */
    public static long reduceFirstDay(Date sDate, Date eDate) throws Exception {
        String pattern = "yyyy-MM-dd";
        DateFormat df1 = new SimpleDateFormat(pattern);
        String date1String = formatDate(sDate, pattern);
        String date2String = formatDate(eDate, pattern);
        Date date1 = null;
        try {
            date1 = df1.parse(date1String);
        } catch (ParseException e) {
            throw new RuntimeException("isLargerThenFirstDay转换日期时出现异常！");
        }
        Date date2 = null;
        try {
            date2 = df1.parse(date2String);
        } catch (ParseException e) {
            throw new RuntimeException("isLargerThenFirstDay转换日期时出现异常！");
        }

        if (null == date1 || null == date2) {
            return 0;
        }
        return date2.getTime() - date1.getTime();
    }

    /**
     * 获取当前系统时间的小时(HH)
     *
     * @return int 当前系统小时HH格式
     * @throws Exception
     */
    public static int getHH() throws Exception {
        DateFormat df = new SimpleDateFormat("HH");
        Date date = new Date(System.currentTimeMillis());
        String str = df.format(date);
        return Integer.parseInt(str);
    }

    /**
     * 获取当前系统时间的分钟数(mm)
     *
     * @return int 当前系统分钟mm格式
     * @throws Exception
     */
    public static int getMM() throws Exception {
        DateFormat df = new SimpleDateFormat("mm");
        Date date = new Date(System.currentTimeMillis());
        String str = df.format(date);
        return Integer.parseInt(str);
    }

    /**
     * 获取当前系统时间的秒数(ss)
     *
     * @return int 当前系统时间的秒数(ss)
     * @throws Exception
     */
    public static int getSS() throws Exception {
        DateFormat df = new SimpleDateFormat("ss");
        Date date = new Date(System.currentTimeMillis());
        String str = df.format(date);
        return Integer.parseInt(str);
    }

    /**
     * 获取输入日期的前后日期
     *
     * @param date
     *      基准日期 yyyy-MM-dd
     * @param dayMark
     *      +代表往后,-代表往前
     * @return String 前后日期（yyyy-MM-dd）
     * @throws Exception
     */
    public static String getOtherDay(String date, int dayMark) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(Calendar.DAY_OF_MONTH, dayMark);
        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime.substring(0, 10);
        return strStart;
    }

    /**
     * 增减 dayMark 数量（计量单位：天）的传入日期 date 后返回字符串数据
     * @param date 原始日期
     * @param formatStr 格式化后返回给用户
     * @param dayMark 增减天数的数量
     * @return
     * @throws Exception
     */
    public static String getOtherDay(String date, String formatStr, int dayMark) throws Exception {
        if(formatStr == null) formatStr = "yyyy-MM-dd";
        DateFormat df = new SimpleDateFormat(formatStr);
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(Calendar.DAY_OF_MONTH, dayMark);
        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime.substring(0, 10);
        return strStart;
    }

    /**
     * 获取日期所在周的第一天(周一)
     *
     * @param date 基准日期yyyy
     *      -MM-dd
     * @return String 周一（yyyy-MM-dd）
     * @throws Exception
     *
     * */
    public static String getWeekFirstDate(String date) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        int days = c.get(Calendar.DAY_OF_WEEK);
        String strStart = "";
        if (days == 1) {
            strStart = getOtherDay(date, -days - 5);
        } else {
            strStart = getOtherDay(date, -days + 2);
        }
        return strStart;
    }

    /**
     * 获取日期所在周的最后一天（周日）
     *
     * @param date 基准日期yyyy
     *      -MM-dd
     * @return String（yyyy-MM-dd）
     * @throws Exception
     *
     * */
    public static String getWeekLastDate(String date) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        int days = c.get(Calendar.DAY_OF_WEEK);
        String strStart = "";
        if (days == 1) {
            strStart = getOtherDay(date, 0);
        } else {
            strStart = getOtherDay(date, 8 - days);
        }
        return strStart;
    }

    /**
     * 获取日期所在周（年的周数）的前后周的周一
     *
     * @param date 基准日期yyyy
     *      -MM-dd
     * @param weekMark 找基准日期
     *      +代表往后,-代表往前
     * @return String 前后周的周一（yyyy-MM-dd）
     * @throws Exception
     *
     * */
    public static String getOtherWeekFirstDate(String date, int weekMark)
            throws Exception {
        String firstDate = getWeekFirstDate(date);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(firstDate);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(Calendar.WEEK_OF_YEAR, weekMark);
        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime.substring(0, 10);
        return strStart;
    }

    /**
     * 获取日期所在季的第一天
     *
     * @param date 基准日期yyyy
     *      -MM-dd
     * @return String
     * @throws Exception
     *
     * */
    public static String getSeasonFirstDate(String date) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        if (month < 3) {
            month = 0;
        } else if (month >= 3 && month < 6) {
            month = 3;
        } else if (month >= 6 && month < 9) {
            month = 6;
        } else if (month >= 9 && month < 12) {
            month = 9;
        }
        c.set(year, month, 1);

        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime.substring(0, 10);
        return strStart;
    }

    /**
     * 获取日期所在季的前后季度的第一天（xxxx-xx-01）
     *
     * @param date
     *      基准日期yyyy-MM-dd
     * @param seasonMark
     *      找基准日期+代表往后,-代表往前
     * @return String
     * @throws Exception
     *
     * */
    public static String getOtherSeasonFirstDate(String date, int seasonMark)
            throws Exception {
        String firstDate = getSeasonFirstDate(date);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(firstDate);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        int month = seasonMark * 3;
        if (month != 0) {
            c.add(Calendar.MONTH, month);
        }
        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime.substring(0, 10);
        return strStart;
    }

    /**
     * 获取日期所在月的第一天 date基准日期
     *
     * @param date
     *      yyyy-MM-dd
     * @return String （yyyy-MM）
     * @throws Exception
     *
     * */
    public static String getMonthFirstDate(String date) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        c.set(year, month, 1);
        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime.substring(0, 10);
        return strStart;
    }

    /**
     * 获取日期所在月的最后一天
     *
     * @param date 基准日期yyyy
     *      -MM-dd
     * @return String yyyy-MM-dd
     * @throws Exception
     *
     * */
    public static String getMonthLastDate(String date) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int dayNum = c.getActualMaximum(Calendar.DAY_OF_MONTH);
        c.set(year, month, dayNum);
        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime.substring(0, 10);
        return strStart;
    }

    /**
     * 获取日期所在月的前后月份的第一天（yyyy-MM-01）
     *
     * @param date 基准日期yyyy
     *      -MM-dd
     * @param monthMark 找基准日期
     *      +代表往后,-代表往前
     * @return String
     * @throws Exception
     *
     * */
    public static String getOtherMonthFirstDate(String date, int monthMark)
            throws Exception {
        String firstDate = getMonthFirstDate(date);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(firstDate);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(Calendar.MONTH, monthMark);
        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime.substring(0, 10);
        return strStart;
    }

    /**
     * 获取日期所在年的第一天
     *
     * @param date 基准日期yyyy
     *      -MM-dd
     * @return String
     * @throws Exception
     *
     * */
    public static String getYearFirstDate(String date) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        int year = c.get(Calendar.YEAR);
        c.set(year, 0, 1);
        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime.substring(0, 10);
        return strStart;
    }

    /**
     * 获取日期所在年的前后年的第一天（yyyy-01-01）
     *
     * @param date
     *      基准日期yyyy-MM-dd
     * @param yearMark 找基准日期+代表往后,-代表往前
     * @return String
     * @throws Exception
     *
     * */
    public static String getOtherYearFirstDate(String date, int yearMark)
            throws Exception {
        String firstDate = getMonthFirstDate(date);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(firstDate);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(Calendar.YEAR, yearMark);
        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime.substring(0, 4);
        return strStart + "-01-01";
    }

    /**
     * 取得同期日期 年同期
     *
     * @param date
     *      yyyy-MM-dd
     * @param year
     *      年份
     * @return 年同期日期yyyy-MM-dd
     * @throws Exception
     */
    public static String getYearTqDay(String date, int year) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(Calendar.YEAR, year);
        String mDateTime = df.format(c.getTime());
        return mDateTime;
    }

    /**
     * 取得同期日期 月同期
     *
     * @param date
     *      yyyy-MM-dd
     * @param month
     *      月份
     * @return 月同期日期yyyy-MM-dd
     * @throws Exception
     */
    public static String getMonthTqDay(String date, int month) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(Calendar.MONTH, month);
        String mDateTime = df.format(c.getTime());
        return mDateTime;
    }

    /**
     * 取得同比月份
     *
     * @param month
     *      月份
     * @return 同比月份
     * @throws Exception
     */
    public static String getTbMonth(String month) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM");
        Date dt = df.parse(month);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(Calendar.YEAR, -1);
        String mDateTime = df.format(c.getTime());
        return mDateTime;
    }

    /**
     * 取得环比月份
     *
     * @param month
     *      月份
     * @return 环比月份
     * @throws Exception
     */
    public static String getHbMonth(String month) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM");
        Date dt = df.parse(month);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(Calendar.MONTH, -1);
        String mDateTime = df.format(c.getTime());
        return mDateTime;
    }

    /**
     * 获取两个日期之间的天数
     *
     * @param sDate
     *      -- 起始日期yyyy-MM-dd
     * @param eDate
     *      -- 结束日期yyyy-MM-dd
     * @return int--天数
     * @throws Exception
     * */
    public static int getDaysOfTwoDate(String sDate, String eDate)
            throws Exception {

        DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");
        DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd");
        Date date1 = df1.parse(sDate);
        Date date2 = df2.parse(eDate);
        if (null == date1 || null == date2) {
            return -1;
        }
        long intervalMilli = date2.getTime() - date1.getTime();
        return (int) (intervalMilli / (24 * 60 * 60 * 1000));
    }

    /**
     * 获取两个月份之间的月数
     *
     * @param sDate
     *      -- 起始月yyyy-MM
     * @param eDate
     *      -- 结束月yyyy-MM
     * @return int--天数
     * @throws Exception
     * */
    public static int getMonthOfTwoMonth(String sDate, String eDate)
            throws Exception {

        DateFormat df = new SimpleDateFormat("yyyy-MM");

        Date date1 = df.parse(sDate);
        Date date2 = df.parse(eDate);
        if (null == date1 || null == date2) {
            return -1;
        }

        Calendar c1 = Calendar.getInstance();
        c1.setTime(date1);
        Calendar c2 = Calendar.getInstance();
        c2.setTime(date2);

        int month1 = c1.get(Calendar.YEAR) * 12 + c1.get(Calendar.MONTH);
        int month2 = c2.get(Calendar.YEAR) * 12 + c2.get(Calendar.MONTH);

        return month2 - month1;
    }

    /**
     * 比较两个日期，第二个参数 eDate 的日期大于 sDate 则返回 true
     * @param sDate 起始日期
     * @param eDate 结束日期
     * @param pattern 日期格式
     * @return boolean 返回比较结果
     * @throws Exception
     */
    public static boolean compareDate(String sDate, String eDate, String pattern)
            throws Exception {

        DateFormat df1 = new SimpleDateFormat(pattern);
        Date date1 = df1.parse(sDate);
        Date date2 = df1.parse(eDate);
        if (null == date1 || null == date2) {
            return false;
        }
        long intervalMilli = date2.getTime() - date1.getTime();
        if (intervalMilli > 0) {
            return true;
        }
        return false;
    }


    /**
     * 比较两个日期的大小，eDate大于sDate则返回1，相反返回-1，相等返回0
     * @param sDate 起始日期
     * @param eDate 终止日期
     * @return eDate大则返回1，等于返回0，小于返回-1
     */
    public static int compareDate(Date sDate, Date eDate) {
        // 任意一个为空则无法判断大小返回异常2
        if (null == sDate || null == eDate) return 2;
        long intervalMilli = eDate.getTime() - sDate.getTime();
        if(intervalMilli > 0) return 1;
        if(intervalMilli < 0) return -1;
        return 0;
    }

    /**
     * 比较两个 Date 类型数据的日期大小（忽略时间）
     * 仅仅比较日期
     * @param sDate
     * @param eDate
     * @return
     */
    public static int compareDateIgnoreTime(Date sDate, Date eDate) {
        if (sDate == null || eDate == null) {
            throw new IllegalArgumentException("Dates cannot be null");
        }

        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(sDate);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(eDate);

        // 只比较年、月、日部分
        int year1 = cal1.get(Calendar.YEAR);
        int month1 = cal1.get(Calendar.MONTH);
        int day1 = cal1.get(Calendar.DAY_OF_MONTH);

        int year2 = cal2.get(Calendar.YEAR);
        int month2 = cal2.get(Calendar.MONTH);
        int day2 = cal2.get(Calendar.DAY_OF_MONTH);

        if (year1 != year2) {
            return year1 > year2 ? 1 : -1;
        } else if (month1 != month2) {
            return month1 > month2 ? 1 : -1;
        } else if (day1 != day2) {
            return day1 > day2 ? 1 : -1;
        } else {
            return 0; // 日期相等
        }
    }

    /**获取两个日期之间的分钟数
     * @param sDate 起始日期 yyyy-MM-dd HH:mm:ss
     * @param eDate 结束日期 yyyy-MM-dd HH:mm:ss
     * @return int--分钟数
     * @throws Exception
     */
    public static int getMinsOfTwoDate(String sDate, String eDate)
            throws Exception {

        DateFormat df1 = new SimpleDateFormat(COMMON_PATTERN);
        DateFormat df2 = new SimpleDateFormat(COMMON_PATTERN);
        Date date1 = df1.parse(sDate);
        Date date2 = df2.parse(eDate);
        if (null == date1 || null == date2) {
            return -1;
        }
        long intervalMilli = date2.getTime() - date1.getTime();
        return (int) (intervalMilli / (60 * 1000));
    }

    /**
     * 获取当前系统时间的字符串
     *
     * @return String -- 当天的整个日期字符串，年月日时分秒，返回格式yyyy-MM-dd HH:mm:ss
     * @throws Exception
     * */
    public static String getToDayAllStr() throws Exception {
        DateFormat df = new SimpleDateFormat(COMMON_PATTERN);
        Date date = new Date(System.currentTimeMillis());
        String str = df.format(date);
        return str;
    }

    /**
     * 获取当前系统日期的字符串
     *
     * @return String-- 当天的年月日字符串，返回格式 yyyy-MM-dd
     * @throws Exception
     * */
    public static String getToDayDateStr() throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date(System.currentTimeMillis());
        String str = df.format(date);
        return str;
    }

    /**
     * 获取当前系统日期的字符串
     *
     * @return String -- 当天的年月日字符串，返回格式 yyyyMMdd
     * */
    public static String getToDayYmd() throws Exception {
        DateFormat df = new SimpleDateFormat("yyyyMMdd");
        Date date = new Date(System.currentTimeMillis());
        String str = df.format(date);
        return str;
    }

    /**获取当前系统时间的指定类型字符串
     * @param pattern 指定的格式
     * @return String-- 当天的指定类型的字符串
     * @throws Exception
     */
    public static String getToDayStrByPattern(String pattern) throws Exception {
        DateFormat df = new SimpleDateFormat(pattern);
        Date date = new Date(System.currentTimeMillis());
        String str = df.format(date);
        return str;
    }

    /**
     * 获取当前系统时间的字符串
     *
     * @return String 当天的时分秒字符串，返回格式HH:mm:ss
     * */
    public static String getToDayHmsStr() throws Exception {
        DateFormat df = new SimpleDateFormat("HH:mm:ss");
        Date date = new Date(System.currentTimeMillis());
        String str = df.format(date);
        return str;
    }

    /**
     * 获取当前系统时间的字符串
     *
     * @return String -- 当天的时分秒字符串，返回格式HHmmss
     * */
    public static String getToDayHms() throws Exception {
        DateFormat df = new SimpleDateFormat("HHmmss");
        Date date = new Date(System.currentTimeMillis());
        String str = df.format(date);
        return str;
    }

    /**获取当前系统指定格式的时间的字符串
     * @param pattern 指定格式
     * @return String 当前系统指定格式时间字符串
     * @throws Exception
     */
    public static String getToDayHmsByPattern(String pattern) throws Exception {
        DateFormat df = new SimpleDateFormat(pattern);
        Date date = new Date(System.currentTimeMillis());
        String str = df.format(date);
        return str;
    }

    /**
     * 获取指定日期的时刻字符串
     *
     * @param dayStr
     *      (yyyy-MM-dd HH:mm:ss)
     * @return String -- 当天的时分秒字符串，返回格式：HHmmss
     * */
    public static String getHmsStrForDateTime(String dayStr) throws Exception {
        DateFormat df = new SimpleDateFormat("HHmmss");
        DateFormat df2 = new SimpleDateFormat(COMMON_PATTERN);
        String str = df.format(df2.parse(dayStr));
        return str;
    }

    /**
     * 日期格式转换 oldPattern 转成 newPattern
     *
     * @param str 要转换格式的日期字符串
     * @param oldPattern 原有格式
     * @param newPattern 目标格式
     * @return String转换格式化后的字符串
     * @throws Exception
     */
    public static String changeDateType(String str, String oldPattern, String newPattern) throws Exception {
        DateFormat df = new SimpleDateFormat(oldPattern);
        DateFormat df1 = new SimpleDateFormat(newPattern);
        return df1.format(df.parse(str));
    }


    /**
     * 获取输入日期的前后几小时的日期时间
     *
     * @param date 基准日期yyyy-MM-dd HH:mm:ss
     * @param dayMark 找基准日期
     *      +代表往后,-代表往前
     * @return
     * @throws Exception
     *
     * */
    public static String getOtherHour(String date, int dayMark)
            throws Exception {
        DateFormat df = new SimpleDateFormat(COMMON_PATTERN);
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(Calendar.HOUR_OF_DAY, dayMark);
        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime;
        return strStart;
    }

    /**
     * 获取前后分钟数
     *
     * @param date yyyy-MM-dd HH:mm:ss
     * @param minuteMark 前后标识+-数值
     * @return 返回
     * @throws Exception
     */
    public static String getOtherMinute(String date, int minuteMark)
            throws Exception {
        DateFormat df = new SimpleDateFormat(COMMON_PATTERN);
        Date dt = df.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(Calendar.MINUTE, minuteMark);
        String mDateTime = df.format(c.getTime());
        String strStart = mDateTime;
        return strStart;
    }



    /**
     * 解析字符串为Date类型
     * @param date 要被解析的日期字符串
     * @param pattern 类型格式，默认yyyy-MM-dd HH:mm:ss
     * @return Date 被解析后的日期
     * @throws Exception
     */
    public static Date parseDate(String date, String pattern) throws Exception {
        Date returnDate = null;
        if (pattern == null || pattern.equals("") || pattern.equals("null")) {
            pattern = COMMON_PATTERN;
        }
        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
        try {
            returnDate = sdf.parse(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnDate;
    }

    /**
     * 将字符串类型的日期转换为日期时间类型
     * @param date 字符串类型的日期
     * @return 返回 Date 类型的日期
     * @throws Exception
     */
    public static Date parseDate(String date) throws Exception {
        Date returnDate = null;
        String pattern = COMMON_PATTERN;

        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
        try {
            returnDate = sdf.parse(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnDate;
    }


    /**
     * 格式化Date类型日期
     * @param date Date类型日期
     * @param pattern 类型格式
     * @return String，被格式化后的日期
     * @throws Exception
     */
    public static String formatDate(Date date, String pattern) throws Exception {
        String returnDate = null;

        if (date == null) {
            return "";
        }

        if (pattern == null || pattern.equals("") || pattern.equals("null")) {
            pattern = COMMON_PATTERN;
        }

        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
        returnDate = sdf.format(date);

        return returnDate;
    }

    public static String formatDate(Date date) throws Exception {
        return formatDate(date,COMMON_PATTERN);
    }

    /**
     * 将时间戳转换为日期时间再转换为 yyyy-MM-dd HH:mm:ss 样式字符串返回
     * @param time
     * @return
     * @throws Exception
     */
    public static String formatDate(long time) throws Exception {
        return formatDate(new Date(time),COMMON_PATTERN);
    }

    public static String formatDateTZ8(long time) {
        SimpleDateFormat sdf = new SimpleDateFormat(COMMON_PATTERN);
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        return sdf.format(new Date(time));
    }

    /**
     * 按照 yyyy-MM-dd HH:mm:ss 格式返回当前日期时间字符串
     * 按照上海时间
     * @return
     */
    public static String formatNow(){
        SimpleDateFormat sdf = new SimpleDateFormat(COMMON_PATTERN);
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        return sdf.format(new Date());
    }

    public static Date getNowTZ() throws Exception {
        Date now = parseDate(formatNow());
        return now;
    }


    /**
     * 得到当前月份yyyy-MM；
     *
     * @return String
     */
    public static String getSystemMonth() {
        java.util.Date date = new java.util.Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM");
        String mDateTime1 = formatter.format(date);
        return mDateTime1;
    }

    /**
     * 获取月所在年的最后一个月
     * @param month 月份
     * @param m
     * @return
     * @throws Exception
     */
    public static String getYearLastMonth(String month, int m) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");

        Date newDate = new Date();
        newDate = format.parse(month);
        Calendar c = Calendar.getInstance();
        c.setTime(newDate);
        c.add(Calendar.YEAR, m);

        newDate.setTime(c.getTimeInMillis());

        return format.format(newDate).substring(0, 4) + "-12";
    }

    /**
     * 获取前后月份
     * + 往后推迟m月
     *
     * @param month
     * @param m
     * @return
     * @throws Exception
     */
    public static String getOtherMonth(String month, int m) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");

        Date newDate = new Date();
        newDate = format.parse(month);
        Calendar c = Calendar.getInstance();
        c.setTime(newDate);
        c.add(Calendar.MONTH, m);

        newDate.setTime(c.getTimeInMillis());

        return format.format(newDate);
    }

    /**
     * 获取前后月份+ 往后推迟m月
     *
     * @param month
     * @param m
     * @return
     * @throws Exception
     */
    public static String getOtherMonthYMD(String month, int m) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        Date newDate = new Date();
        newDate = format.parse(month);
        Calendar c = Calendar.getInstance();
        c.setTime(newDate);
        c.add(Calendar.MONTH, m);

        newDate.setTime(c.getTimeInMillis());

        return format.format(newDate);
    }

    /**
     * 根据年月字符串得到那个月的总天数
     * @param monthStr yyyy-MM
     * @return int 总天数
     * @throws Exception
     */
    public static int getDaysOfMonth(String monthStr) throws Exception {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        Date date = format.parse(monthStr);
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        int dayNum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        return dayNum;
    }

    /**
     * 获取指定时刻前后指定步长的时刻
     *
     * @param time
     *      时刻HH:mm:ss
     * @param m
     *      步长(+-m) 0:输出原来的时刻，+1输出后一个时刻，-1输出前一个时刻
     * @return String HH:mm:ss
     * @throws Exception
     */
    public static String getBeforeAfterTimeForMin(String time, int m)
            throws Exception {
        Calendar now = Calendar.getInstance();
        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
        Date newDate = new Date();
        newDate = format.parse(time);
        now.setTime(newDate);
        now.add(Calendar.MINUTE, m);
        return format.format(now.getTime());
    }

    /**
     * 获取指定格式的前后时间
     *
     * @param time
     * @param m
     *      (0:输出原来的时刻，+1输出后一个时刻，-1输出前一个时刻)
     * @param pattern
     *      类型的格式必须被time的格式所包含
     * @return
     * @throws Exception
     */
    public static String getBeforeAfterDateTimeByTime(String time, int m,
                                                      String pattern) throws Exception {
        Calendar now = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);

        Date newDate = new Date();
        newDate = sdf.parse(time);
        now.setTime(newDate);
        now.add(Calendar.MINUTE, m);

        return sdf.format(now.getTime());
    }

    /**
     * 在当前时间的基础上增减时间
     * @param type 类似 Calendar.MINUTE
     * @param amount
     * @return
     */
    public static Date add(int type,int amount){
        Calendar now = Calendar.getInstance();
        now.add(type,amount);
        return now.getTime();
    }

    public static Date add(Date date,int type,int amount){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(type,amount);
        return calendar.getTime();
    }

    /**
     * 使用传入参数和今天比较是否在同一天，是则返回true
     * @param stdDate 默认格式：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static boolean isSameDay(String stdDate) {
        LocalDate stdDay = string2LocalDate(stdDate,"");
        int iDay = stdDay.getDayOfMonth();
        int nowDay = LocalDate.now().getDayOfMonth();
        return iDay == nowDay ? true:false;
    }

    /*
     * @Description: 格式化 LocalDateTime 类型，第二个参数 dateFormat 为可选，可填写 null 和空字符串
     * @param: [localDateTime]
     * @param: 想要的日期时间的格式，如果填写 null 或者空字符串表示使用默认的格式：yyyy-MM-dd HH:mm:ss
     * @return: java.lang.String
     * @Date: 2025年2月27日 19:42:58
     */
    public static String localDateTimeToString(LocalDateTime localDateTime, String dateFormat) {
        dateFormat = Optional.ofNullable(dateFormat).orElse("");
        if(dateFormat.length() == 0) dateFormat = COMMON_PATTERN;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(dateFormat);
        return dateTimeFormatter.format(localDateTime);
    }

    /**
     * 检查两个 LocalDateTime 类型的日期是否是同一天
     * 将其转换为 yyyy-MM-dd 格式后对比字符串是否相等
     * @param t1 LocalDateTime类型日期
     * @param t2 LocalDateTime类型日期
     * @return true表示是同一天
     */
    public static Boolean isSameDay(LocalDateTime t1, LocalDateTime t2) {
        String formatStr = "yyyy-MM-dd";
        String s1 = localDateTimeToString(t1,formatStr);
        String s2 = localDateTimeToString(t2,formatStr);
        return s1.equalsIgnoreCase(s2);
    }
    /*
     * @Description: localdatetime转换为毫秒数
     * @param: [ldt]
     * @return: long
     * @Date: 2019/12/20
     */
    public static long localDateTimeToLong(LocalDateTime ldt) {
        return ldt.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }
    /*
     * @Description: 毫秒数转换为localdatetime
     * @param: [time]
     * @return: java.time.LocalDateTime
     * @Date: 2019/12/20
     */
    public static LocalDateTime longToLocalDateTime(long time) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault());
    }

    public static boolean isSameMonth(String stdDate){
        LocalDate stdDay = string2LocalDate(stdDate,"");
        int iDay = stdDay.getMonthValue();
        int nowDay = LocalDate.now().getMonthValue();
        return iDay == nowDay ? true:false;
    }

    public static boolean isSameYear(String stdDate){
        LocalDate stdDay = string2LocalDate(stdDate,"");
        int iDay = stdDay.getYear();
        int nowDay = LocalDate.now().getYear();
        return iDay == nowDay ? true:false;
    }


    public static LocalDate string2LocalDate(String strDate, String format) {
        if( format.length()<=0 ) format = COMMON_PATTERN;
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format);
        LocalDate localDate = LocalDate.parse(strDate, dtf);
        return localDate;
    }

    public static LocalDateTime string2LocalDateTime(String strDate, String format) {
        if( format.length()<=0 ) format = COMMON_PATTERN;
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format);
        LocalDateTime localDateTime = LocalDateTime.parse(strDate, dtf);
        return localDateTime;
    }

    // 返回指定日期的年份
    public static int getYY(Date date) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy");
        String str = df.format(date);
        return Integer.parseInt(str);
    }

    // 返回指定日期的月份
    public static int getMon(Date date) throws Exception {
        DateFormat df = new SimpleDateFormat("MM");
        String str = df.format(date);
        return Integer.parseInt(str);
    }

    // 返回指定日期的日
    public static int getDD(Date date) throws Exception {
        DateFormat df = new SimpleDateFormat("dd");
        String str = df.format(date);
        return Integer.parseInt(str);
    }

    // 返回指定日期的小时
    public static int getHH(Date date) throws Exception {
        DateFormat df = new SimpleDateFormat("HH");
        String str = df.format(date);
        return Integer.parseInt(str);
    }

    // 返回指定日期的分钟
    public static int getMM(Date date) throws Exception {
        DateFormat df = new SimpleDateFormat("mm");
        String str = df.format(date);
        return Integer.parseInt(str);
    }

    // 返回指定日期的秒钟
    public static int getSS(Date date) throws Exception {
        DateFormat df = new SimpleDateFormat("ss");
        String str = df.format(date);
        return Integer.parseInt(str);
    }

    public static Date calendar2Date(int year, int month, int day) {
        Calendar calendar = Calendar.getInstance();//日历类的实例化
        calendar.set(year, month - 1, day);//设置日历时间，月份必须减一
        Date date = calendar.getTime(); // 从一个 Calendar 对象中获取 Date 对象
        return date;
    }

    /**
     * Date类型转换为Calendar类型
     * @param date Date类型日期
     * @return
     */
    public static Calendar date2Calendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    //#region LocalDateTime、LocalDate、LocalTime和Date互相转换
    public static LocalDateTime date2LocalDateTime(java.util.Date date) {/*java.util.Date --> java.time.LocalDateTime*/
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }
    public static LocalDate date2LocalDate(java.util.Date date) {/*java.util.Date --> java.time.LocalDate*/
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        return localDateTime.toLocalDate();
    }
    public static LocalTime date2LocalTime(java.util.Date date) {/*java.util.Date --> java.time.LocalTime*/
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        return localDateTime.toLocalTime();
    }
    public static Date localDateTime2Udate(LocalDateTime localDateTime) {/*java.time.LocalDateTime --> java.util.Date*/
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDateTime.atZone(zone).toInstant();
        return Date.from(instant);
    }
    public static Date localDate2Udate(LocalDate localDate) {/*java.time.LocalDate --> java.util.Date*/
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
        return Date.from(instant);
    }
    public static Date localTime2Udate(LocalTime localTime) {/*java.time.LocalTime --> java.util.Date*/
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDateTime.atZone(zone).toInstant();
        return Date.from(instant);
    }
    //#endregion

    /**
     * 给定一个开始时间，设置间隔时间，返回24小时内的时间数组
     * 例如起始时间是早晨6点，间隔是4小时，则会返回：6，10，14，18，22，2 构成的数组
     * LocalTime lt = LocalTime.now();// 12:36:08.163 作为起始时间则返回下面的数组
     * [12:36:08.163, 16:36:08.163, 20:36:08.163, 00:36:08.163, 04:36:08.163, 08:36:08.163]
     * @param startTime 第一个时间，返回数组中永远会有该时间
     * @param unit 间隔时间，2024年4月22日制作本功能时只支持小时，传入-1则默认为按照小时计算
     * @param amount 间隔数量
     * @return
     */
    public static List<LocalTime> getIntervalTimeList(LocalTime startTime, int unit, int amount){
        if(amount <= 0) throw new RuntimeException("间隔时间必须大于0！");
        if(!(Calendar.HOUR == unit)) throw new RuntimeException("暂时只支持按照小时生成数据！");

        List<LocalTime> ret = new ArrayList<>();
        ret.add(startTime);

        int totalAmount = amount;
        LocalTime nextTime = startTime.plusHours(amount);
        while(totalAmount < 24){// 24小时以内（获取一天内的多个时间间隔）
            ret.add(nextTime);
            nextTime = nextTime.plusHours(amount);
            totalAmount += amount;
        }
        return ret;
    }

    /**
     * 调用 getIntervalTimeList，默认按照小时间隔
     * @param startTime
     * @param amount
     * @return
     */
    public static List<LocalTime> getIntervalTimeList(LocalTime startTime, int amount){
        return getIntervalTimeList(startTime,Calendar.HOUR,amount);
    }

    public static List<Date> getIntervalTimeList(Date startTime, int unit, int amount){
        if(amount <= 0) throw new RuntimeException("间隔时间必须大于0！");
        if(!(Calendar.HOUR == unit)) throw new RuntimeException("暂时只支持按照小时生成数据！");

        LocalTime localTime = date2LocalTime(startTime);
        List<Date> ret = new ArrayList<>();
        ret.add(startTime);

        int totalAmount = amount;
        LocalTime nextTime = localTime.plusHours(amount);
        while(totalAmount < 24){// 24小时以内（获取一天内的多个时间间隔）
            ret.add(localTime2Udate(nextTime));
            nextTime = nextTime.plusHours(amount);
            totalAmount += amount;
        }
        return ret;
    }

    public static List<Date> getIntervalTimeList(Date startTime, int amount){
        return getIntervalTimeList(startTime,Calendar.HOUR,amount);
    }

    /**
     *
     * @param startTime 带有日期时间
     * @param amount 24小时内按照分钟分割的数量
     * @return
     */
    public static List<Date> getIntervalTimeListMinute(Date startTime, int amount){
        if(amount <= 0) throw new RuntimeException("间隔时间必须大于0！");
        int interval = amount;// 一个周期的长度
        int qty = 24 * 60 / amount;// 分割的目标个数
        List<Date> ret = new ArrayList<>();
        ret.add(startTime);
        Date nextDate = null;
        LocalDateTime nextLocalDateTime = date2LocalDateTime(startTime);
        for (int i = 1; i < qty; i++) {
            nextLocalDateTime = nextLocalDateTime.plusMinutes(interval);
            nextDate = localDateTime2Udate(nextLocalDateTime);
            ret.add(nextDate);
        }
        return ret;
    }

    /**
     * 以24小时为最大范围创建多个时间段构成的集合，例如下面是以 20:11:38 为开始时间
     * 时长12小时为一个时间段生成的两个时间段构成的集合：（起始终止key分别为：start,end）
     * [
     * {start=Tue Apr 23 20:11:38 CST 2024, end=Tue Apr 23 08:11:37 CST 2024},
     * {start=Tue Apr 23 08:11:38 CST 2024, end=Tue Apr 23 20:11:37 CST 2024}
     * ]
     * @param startTime 第一个时间段的起始时间
     * @param amount 时间段的长度（小时）
     * @return 时间段 Map 构成的集合
     */
    public static List<Map<String,Date>> getTimeRangeList(Date startTime, int amount){
        List<Date> intervalTimeList = getIntervalTimeList(startTime, amount);
        if(intervalTimeList == null || intervalTimeList.size() == 0) return null;

        List<Map<String,Date>> ret = new ArrayList<>();
        Map<String,Date> map = null;
        for (int i = 0; i < intervalTimeList.size(); i++) {
            map = new HashMap<>();
            map.put("start",intervalTimeList.get(i));

            int j = i+1;
            if(j > intervalTimeList.size()) break;

            Date endDate = null;
            // 最后一个元素的截止时间是第一个元素减少一秒
            if(j == intervalTimeList.size()) endDate = intervalTimeList.get(0);
            else endDate = intervalTimeList.get(j);

            LocalTime localTime = date2LocalTime(endDate);
            //localTime = localTime.plusSeconds(-1); 设计为通用方法，这里不可默认减少一秒
            endDate = localTime2Udate(localTime);
            map.put("end", endDate);
            ret.add(map);
        }
        return ret;
    }

    public static List<Map<String,Date>> getTimeRangeListMinute(Date startTime, int amount){
        List<Date> intervalTimeList = getIntervalTimeListMinute(startTime, amount);
        if(intervalTimeList == null || intervalTimeList.size() == 0) return null;

        List<Map<String,Date>> ret = new ArrayList<>();
        Map<String,Date> map = null;
        for (int i = 0; i < intervalTimeList.size(); i++) {
            map = new HashMap<>();
            map.put("start",intervalTimeList.get(i));

            int j = i+1;
            if(j > intervalTimeList.size()) break;

            Date endDate = null;
            // 最后一个元素的截止时间是第一个元素减少一秒
            if(j == intervalTimeList.size()) endDate = intervalTimeList.get(0);
            else endDate = intervalTimeList.get(j);

            LocalTime localTime = date2LocalTime(endDate);
            //localTime = localTime.plusSeconds(-1); 设计为通用方法，这里不可默认减少一秒
            endDate = localTime2Udate(localTime);
            map.put("end", endDate);
            ret.add(map);
        }
        return ret;
    }

    /**
     * 比较两个日期，等于今天返回0，大于今天返回大于0，小于今天返回负数
     * @param targetDate 拿该日期和当前日期比较
     * @return
     */
    public static int compareNowDay(Date targetDate){
        LocalDate targetLocalDate = date2LocalDate(targetDate);
        return targetLocalDate.compareTo(LocalDate.now());
    }

    /**
     * 比较两个日期的月份，等于今天返回0，大于今天返回大于0，小于今天返回负数
     * @param targetDate 拿该日期和当前日期比较
     * @return
     */
    public static int compareNowMonth(Date targetDate){
        LocalDate targetLocalDate = date2LocalDate(targetDate);
        return targetLocalDate.getMonth().compareTo(LocalDate.now().getMonth());
    }

    /**
     * 比较两个日期的年份，等于今天返回0，大于今天返回大于0，小于今天返回负数
     * @param targetDate 拿该日期和当前日期比较
     * @return
     */
    public static int compareNowYear(Date targetDate){
        LocalDate targetLocalDate = date2LocalDate(targetDate);
        int targetYear = targetLocalDate.getYear();
        int nowYear = LocalDate.now().getYear();
        return targetYear - nowYear;
    }

    /**
     *  拿后者 edate 对比前者 sdate，如果后者大则返回 1
     *  相反则返回 -1，相等则返回0
     * @param sdate
     * @param edate
     * @return
     */
    public static int isBiggerDate(Date sdate, Date edate,String datePattern) throws Exception {
        if(sdate == null && edate == null) return 0;
        if(sdate == null && edate != null) return 1;
        if(sdate != null && edate == null) return -1;

        String formatStr = Optional.ofNullable(datePattern).orElse("yyyy-MM-dd");
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
        String sdateStr = sdf.format(sdate);
        String edateStr = sdf.format(edate);
        Date sdateDay = parseDate(sdateStr, formatStr);
        Date edateDay = parseDate(edateStr, formatStr);

        long timeSdate = sdateDay.getTime();
        long timeEdate = edateDay.getTime();
        if(timeEdate > timeSdate) return 1;
        if(timeEdate < timeSdate) return -1;
        if(timeEdate == timeSdate) return 0;
        throw new RuntimeException("比较日期" + sdate + "和" + edate + "时出现异常！");
    }

    /**
     * 参数2时间对比参数1时间(同时对比日期)，大于返回1，等于返回0，小于返回-1
     * @param sdate 精确到秒的时间
     * @param edate 精确到秒的时间
     * @param timePattern 保留NULL则默认按照 yyyy-MM-dd HH:mm:ss 格式化时间后对比大小
     * @return
     * @throws Exception
     */
    public static int isBiggerTime(Date sdate, Date edate,String timePattern) throws Exception {
        if(sdate == null && edate == null) return 0;
        if(sdate == null && edate != null) return 1;
        if(sdate != null && edate == null) return -1;

        String formatStr = Optional.ofNullable(timePattern).orElse(COMMON_PATTERN);
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
        String sdateStr = sdf.format(sdate);
        String edateStr = sdf.format(edate);
        Date sdateDay = parseDate(sdateStr, formatStr);
        Date edateDay = parseDate(edateStr, formatStr);

        long timeSdate = sdateDay.getTime();
        long timeEdate = edateDay.getTime();
        if(timeEdate > timeSdate) return 1;
        if(timeEdate < timeSdate) return -1;
        if(timeEdate == timeSdate) return 0;
        throw new RuntimeException("比较日期" + sdate + "和" + edate + "时出现异常！");
    }

    /**
     * 参数中带有日期，但是仅仅对比时间
     * @param sdate 带有日期也只会对比时间
     * @param edate 带有日期也只会对比时间
     * @return edate>sdate返回1,edate=sdate返回0,edate<sdate返回-1
     * @throws Exception
     */
    public static int isBiggerTimeOnly(Date sdate, Date edate) throws Exception {
        if(sdate == null && edate == null) return 0;
        if(sdate == null && edate != null) return 1;
        if(sdate != null && edate == null) return -1;

        String formatStr = COMMON_PATTERN;
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
        String sdateStr = sdf.format(sdate);
        String edateStr = sdf.format(edate);

        String stime = sdateStr.substring(11).replace(":","");
        String etime = edateStr.substring(11).replace(":","");
        int si = Integer.parseInt(stime);
        int ei = Integer.parseInt(etime);

        if(ei > si) return 1;
        if(ei < si) return -1;
        if(ei == si) return 0;
        throw new RuntimeException("比较日期" + sdate + "和" + edate + "时出现异常！");
    }

    /**
     * 检测 checkedDate 是否在时间段内，两边封闭的括号
     * 是则返回 true，相反返回 false
     * 要求3个参数的格式都是：2025-05-28 11:12:13
     * 计算过程中会忽略日期，只计算时间，时间要求是24小时制
     * @param checkedDate 被检测的时间（会忽略日期）
     * @param sdate 起始时间（忽略日期）
     * @param edate 终止时间（忽略日期）
     * @return checkedDate在时间段内返回true
     * @throws Exception
     */
    public static boolean isBetweenTime(Date checkedDate, Date sdate, Date edate) throws Exception {
        if(sdate == null && edate == null) throw new RuntimeException("参数不可为空");
        if(sdate == null && edate != null) throw new RuntimeException("参数不可为空");
        if(sdate != null && edate == null) throw new RuntimeException("参数不可为空");

        Integer sint = getTimeStrInt(sdate);
        Integer eint = getTimeStrInt(edate);
        Integer cint = getTimeStrInt(checkedDate);
        if(eint < sint) throw new RuntimeException("设置的终止时间小于起始时间，无法对比大小！");
        if(cint >= sint && cint <= eint) return true;
        return false;
    }

    // 将 LocalDateTime 类型转换为 LocalDate 类型
    public static LocalDate localDateTime2LocalDate(LocalDateTime localDateTime){
        return localDateTime.toLocalDate();
    }
    /**
     * 判断传入日期是否今天，是则返回true
     * @param date
     * @return
     */
    public static boolean isToday(LocalDate date) {
        LocalDate today = LocalDate.now();  // 获取今天的日期
        return date.equals(today);  // 比较日期是否相等
    }
    public static boolean isToday(LocalDateTime date) {
        LocalDate today = LocalDate.now();  // 获取今天的日期
        return date.toLocalDate().equals(today);
    }
    public static boolean isInThisMonth(LocalDateTime dateTime) {
        LocalDateTime now = LocalDateTime.now();  // 获取当前时间
        return dateTime.getYear() == now.getYear() && dateTime.getMonth() == now.getMonth();  // 比较年份和月份
    }
    public static boolean isInThisWeek(LocalDateTime dateTime) {
        LocalDateTime now = LocalDateTime.now();  // 获取当前时间
        // 获取当前周的星期一
        LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        // 获取当前周的星期天
        LocalDateTime endOfWeek = now.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));

        // 判断传入日期是否在当前周的范围内
        return !dateTime.isBefore(startOfWeek) && !dateTime.isAfter(endOfWeek);
    }

    /**
     * 比较两个 LocalDateTime 类型的日期时间变量，只对比日期，不对比时间
     * 两者是同一天返回0，前者大于后者返回1，前者小于后者返回-1
     * @param t1 LocalDateTime类型日期时间
     * @param t2 LocalDateTime类型日期时间
     * @return 同一天返回0，前者大返回1，前者小返回-1
     */
    public static int compareDateTo(LocalDateTime t1, LocalDateTime t2){
        String formatString = "yyyyMMdd";
        String t1Date = t1.format(DateTimeFormatter.ofPattern(formatString));
        String t2Date = t2.format(DateTimeFormatter.ofPattern(formatString));
        int t1int = Integer.parseInt(t1Date);
        int t2int = Integer.parseInt(t2Date);
        if(t1int == t2int) return 0;
        if(t1int > t2int) return 1;
        return -1;
    }

    /**
     * 对比两个  LocalDateTime 类型的时间大小
     * 精确到毫秒
     * @param t1
     * @param t2
     * @return t1大于t2返回1，t1小于t2返回-1，相等返回0
     */
    public static int compareTimeTo(LocalDateTime t1,LocalDateTime t2, TimeMeasurementUnit unit){
        String formatString = "";
        if(unit == TimeMeasurementUnit.MILLISECOND){
            formatString = "yyyyMMddHHmmssSSS";
        }

        long l1 = localDateTimeToLong(t1);
        long l2 = localDateTimeToLong(t2);
        if(l1 > l2 ) return 1;
        if(l1 < l2 ) return -1;
        return 0;
    }

    /**
     * LocalDateTime增加毫秒单位的数值
     * @param t 原 LocalDateTime 日期时间类型
     * @param addend 累加的毫秒数
     * @return
     */
    public static LocalDateTime localDateTimeAdd(LocalDateTime t, long addend){
        long l = localDateTimeToLong(t) + addend;
        return longToLocalDateTime(l);
    }

    /**
     * 格式化 LocalDateTime 日期时间类型数据，第二个参数可选
     * @param t LocalDateTime 日期时间类型
     * @param pattern 日期格式字符串
     * @return
     */
    public static String formatDate(LocalDateTime t, String pattern){
        String s = Optional.ofNullable(pattern).orElse("");
        if(s.length() == 0) pattern = COMMON_PATTERN;
        return localDateTimeToString(t,pattern);
    }

    /**
     * 计算传入的时间距离当前时间的时长
     * 根据第二个参数 unit 返回数量，计量单位是秒则返回相差的秒数
     * 计量单位是分钟则返回相差的分钟数量
     * @param localDateTime 被检测的时间
     * @param unit 计量单位，决定返回数据的大小
     * @return
     */
    public static Long getDurationTillNow(LocalDateTime localDateTime,TimeMeasurementUnit unit){
        Duration between = Duration.between(localDateTime, LocalDateTime.now());
        if(unit.equals(TimeMeasurementUnit.MILLISECOND)){
            return between.toMillis();
        }else if(unit.equals(TimeMeasurementUnit.SECOND)){
            return between.toMillis() / 1000;
        }else if(unit.equals(TimeMeasurementUnit.MINUTE)){
            return between.toMinutes();
        }else if(unit.equals(TimeMeasurementUnit.HOUR)){
            return between.toHours();
        }else if(unit.equals(TimeMeasurementUnit.DAY)){
            return between.toDays();
        }
        return -1L;
    }

    public static String getCronString(Date date){
        if(date == null) return "";
        SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); // 可选，设置时区
        String formattedDate = sdf.format(date);

        // 拆分并构建 Cron 表达式
        String[] dateParts = formattedDate.split(" ");
        String cronExpression = String.format(
                "%s %s %s %s %s ?",  // 周固定为 ?（不指定）
                dateParts[0], // 秒
                dateParts[1], // 分
                dateParts[2], // 时
                dateParts[3], // 日
                dateParts[4]  // 月
        );

        return cronExpression;
    }

    public static void main(String[] args) throws Exception {
// 创建测试日期（注意：月份从0开始，0表示一月）
        Calendar cal = Calendar.getInstance();

        // 日期1: 2023年5月15日 10:30:45
        cal.set(2023, 4, 15, 10, 30, 45);
        Date date1 = cal.getTime();

        // 日期2: 2023年5月15日 14:20:30 (同一天，不同时间)
        cal.set(2023, 4, 15, 14, 20, 30);
        Date date2 = cal.getTime();

        // 日期3: 2023年5月16日 09:15:00 (下一天)
        cal.set(2023, 4, 16, 9, 15, 0);
        Date date3 = cal.getTime();

        // 测试比较
        System.out.println("date1 和 date2 比较: " + compareDateIgnoreTime(date1, date2)); // 应该输出"相等"
        System.out.println("date1 和 date3 比较: " + compareDateIgnoreTime(date1, date3)); // 应该输出"小于"
        System.out.println("date3 和 date1 比较: " + compareDateIgnoreTime(date3, date1)); // 应该输出"大于"
    }

}

